package org.example.curriculum_design_6_16.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.example.curriculum_design_6_16.entity.pojo.CompetitionCatalog;
import org.example.curriculum_design_6_16.entity.pojo.CompetitionParticipation;
import org.example.curriculum_design_6_16.entity.vo.CompetitionParticipationVo;
import org.example.curriculum_design_6_16.entity.vo.Result;
import org.example.curriculum_design_6_16.mapper.CompetitionCatalogMapper;
import org.example.curriculum_design_6_16.service.CompetitionParticipationService;
import org.example.curriculum_design_6_16.mapper.CompetitionParticipationMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author 郑凯
 * @description 针对表【competition_participation】的数据库操作Service实现
 * @createDate 2025-06-22 21:30:17
 */
@Service
public class CompetitionParticipationServiceImpl extends ServiceImpl<CompetitionParticipationMapper, CompetitionParticipation>
        implements CompetitionParticipationService{
    @Autowired
    private CompetitionParticipationMapper participationMapper;

    @Autowired
    private CompetitionCatalogMapper catalogMapper;
    @Autowired
    private CompetitionCatalogMapper competitionCatalogMapper;

    @Override
    public List<CompetitionParticipationVo> getAllParticipations() {
        List<CompetitionParticipation> participations = participationMapper.selectAll();
        List<CompetitionParticipationVo> participationVos = new ArrayList<>();

        for (CompetitionParticipation participation : participations) {
            participationVos.add(convertToVo(participation));
        }

        return participationVos;
    }

    @Override
    public CompetitionParticipationVo getParticipationById(Integer id) {
        CompetitionParticipation participation = participationMapper.selectById(id);
        if (participation == null) throw new RuntimeException("未找到ID为" + id + "的参赛记录");
        
        return convertToVo(participation);
    }

    @Override
    public List<CompetitionParticipationVo> getParticipationsByStudentId(String studentId) {
        List<CompetitionParticipation> participations = participationMapper.selectByStudentId(studentId);
        List<CompetitionParticipationVo> participationVos = new ArrayList<>();

        for (CompetitionParticipation participation : participations) {
            participationVos.add(convertToVo(participation));
        }

        return participationVos;
    }

    @Override
    public List<CompetitionParticipationVo> getParticipationsByStudentIdAndYear(String studentId, String academicYear) {
        List<CompetitionParticipation> participations = participationMapper.selectByStudentIdAndYear(studentId, academicYear);
        List<CompetitionParticipationVo> participationVos = new ArrayList<>();

        for (CompetitionParticipation participation : participations) {
            participationVos.add(convertToVo(participation));
        }

        return participationVos;
    }

    @Override
    public List<CompetitionParticipationVo> getParticipationsByCompetitionId(Integer competitionId) {
        List<CompetitionParticipation> participations = participationMapper.selectByCompetitionId(competitionId);
        List<CompetitionParticipationVo> participationVos = new ArrayList<>();

        for (CompetitionParticipation participation : participations) {
            participationVos.add(convertToVo(participation));
        }

        return participationVos;
    }

    /**
     * 将CompetitionParticipation转换为CompetitionParticipationVo
     * @param participation 参赛记录
     * @return 参赛记录VO
     */
    private CompetitionParticipationVo convertToVo(CompetitionParticipation participation) {
        CompetitionParticipationVo vo = new CompetitionParticipationVo();
        vo.setId(participation.getId());
        vo.setStudentId(participation.getStudentId());
        vo.setCompetitionId(participation.getCompetitionId());
        
        // 查询竞赛目录获取竞赛名称、级别、类别
        CompetitionCatalog catalog = catalogMapper.selectById(participation.getCompetitionId());
        if (catalog != null) {
            vo.setCompetitionName(catalog.getCompetitionName());
            vo.setLevel(catalog.getLevel() != null ? catalog.getLevel().toString() : null);
            vo.setCategory(catalog.getCategory() != null ? catalog.getCategory().toString() : null);
        }
        
        vo.setScore(participation.getScore());
        vo.setParticipationDate(participation.getParticipationDate());
        vo.setStatus((String) participation.getStatus());
        vo.setAcademicYear(participation.getAcademicYear());
        vo.setCreatedAt(participation.getCreatedAt());
        vo.setIsTeamLeader(participation.getIsTeamLeader());
        vo.setProofUrl(participation.getProofUrl());
        vo.setReviewComment(participation.getReviewComment());
        vo.setTeamSize(participation.getTeamSize());
        vo.setUpdatedAt(participation.getUpdatedAt());
        vo.setAwardLevel((String) participation.getAwardLevel());
        
        return vo;
    }

    @Override
    @Transactional
    public int addParticipation(CompetitionParticipation participation) {
        // 设置默认状态为已通过
        if (participation.getStatus() == null) {
            participation.setStatus("approved");
        }
        if (participation.getReviewComment() == null) {
            participation.setReviewComment("自动通过");
        }
        calculateScore(participation);
        return participationMapper.insert(participation);
    }

    @Override
    @Transactional
    public int updateParticipation(CompetitionParticipation participation) {
        // 设置默认状态为已通过
        if (participation.getStatus() == null) {
            participation.setStatus("approved");
        }
        if (participation.getReviewComment() == null) {
            participation.setReviewComment("自动通过");
        }
        calculateScore(participation);
        return participationMapper.update(participation);
    }

    @Override
    public int deleteParticipation(Integer id) {
        return participationMapper.delete(id);
    }

    @Override
    @Transactional
    public int approveParticipation(Integer id, String reviewComment) {
        return participationMapper.updateStatus(id, "approved", reviewComment);
    }

    @Override
    @Transactional
    public int rejectParticipation(Integer id, String reviewComment) {
        return participationMapper.updateStatus(id, "rejected", reviewComment);
    }

    @Override
    public double getSum(String studentId) {
        List<CompetitionParticipation> list = participationMapper.selectByStudentId(studentId);
        return list.stream().mapToDouble(CompetitionParticipation::getScore).sum();
    }

    @Override
    public double getSum(String studentId, String academicYear) {
        List<CompetitionParticipation> list = participationMapper.selectByStudentIdAndYear(studentId, academicYear);
        return list.stream()
                .filter(p -> "approved".equals(p.getStatus())) // 只计算已审核通过的
                .mapToDouble(CompetitionParticipation::getScore)
                .sum();
    }

    private void calculateScore(CompetitionParticipation participation) {
        // 1. 获取竞赛信息
        CompetitionCatalog catalog = catalogMapper.selectById(participation.getCompetitionId());
        if (catalog == null) {
            participation.setScore(0.0); // 规则⑥：无效竞赛不计分
            return;
        }

        // 2. 规则⑥：检查是否学校认定
        if (catalog.getIsOfficial() == 0 && !"CCF".equals(catalog.getCategory())) {
            participation.setScore(0.0);
            return;
        }

        // 3. 规则④：检查无效奖项
        if (isInvalidAward((String) participation.getAwardLevel())) {
            participation.setScore(0.0);
            return;
        }

        // 4. 计算基础分
        double baseScore = calculateBaseScore(participation, catalog);

        // 5. 规则②：省级及以下个人赛调整
        if (catalog.getIsTeamCompetition() == 0 &&
                ("provincial".equals(catalog.getLevel()) || "municipal".equals(catalog.getLevel()))) {
            baseScore *= 0.8;
        }

        // 6. 规则①：检查是否为同一竞赛最高奖项
        if (!checkHighestAward(participation, baseScore)) {
            participation.setScore(0.0);
            return;
        }

        // 7. 规则②：团体赛分数分配
        if (catalog.getIsTeamCompetition() == 1 && participation.getIsTeamLeader() == 0) {
            participation.setScore(0.0); // 非组长成员需组长分配
            return;
        }

        // 8. 特殊规则：CCF非认定比赛
        if ("CCF".equals(catalog.getCategory()) && catalog.getIsOfficial() == 0) {
            participation.setScore(0.2); // 固定0.2分
            return;
        }

        participation.setScore(baseScore);
    }

    // 计算基础分数（规则③）
    private double calculateBaseScore(CompetitionParticipation participation, CompetitionCatalog catalog) {
        if (participation.getAwardLevel().equals("特等奖")) {
            if(Objects.equals(catalog.getSpecialPrizeHandling(), "upgrade")) {
                return catalog.getFirstPrizeScore();
            }
            else {
                return catalog.getSpecialPrizeScore();
            }
        } else if (participation.getAwardLevel().equals("一等奖")) {
            return catalog.getFirstPrizeScore();
        } else if (participation.getAwardLevel().equals("二等奖")) {
            return catalog.getSecondPrizeScore();
        } else if (participation.getAwardLevel().equals("三等奖")) {
            return catalog.getThirdPrizeScore();
        }
        return 0.0;
    }

    // 检查是否为无效奖项（规则④）
    private boolean isInvalidAward(String awardLevel) {
        return "优胜奖".equals(awardLevel) ||
                "参赛奖".equals(awardLevel) ||
                "other".equals(awardLevel);
    }

    // 检查是否为该学生在同一竞赛中的最高奖项
    private boolean checkHighestAward(CompetitionParticipation newParticipation, Double newScore) {
        // 获取该学生在该竞赛中的所有参赛记录
        List<CompetitionParticipation> existingParticipations =
                participationMapper.selectByStudentIdAndCompetitionId(
                        newParticipation.getStudentId(),
                        newParticipation.getCompetitionId());

        // 排除当前记录（如果是更新操作）
        existingParticipations = existingParticipations.stream()
                .filter(p -> !p.getId().equals(newParticipation.getId()))
                .collect(Collectors.toList());

        // 查找已有记录中的最高分
        Double maxScore = existingParticipations.stream()
                .map(CompetitionParticipation::getScore)
                .max(Double::compare)  // 改为Double比较
                .orElse(0.0);

        // 新分数必须高于现有最高分才有效
        return newScore > maxScore;
    }
}